package com.example.zqq.mysnake.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

import com.example.zqq.mysnake.R;
import com.example.zqq.mysnake.model.Body;
import com.example.zqq.mysnake.model.Food;
import com.example.zqq.mysnake.model.Head;
import com.example.zqq.mysnake.model.Snake;
import com.example.zqq.mysnake.model.SnakeDirection;
import com.example.zqq.mysnake.model.Stone;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by Administrator on 2017/10/30.
 */

public class SnakeView extends View {

    private Context context;
    private Bitmap headBitmap;
    private Bitmap bodyBitmap;
    private Bitmap foodBitmap;
    private Bitmap stoneBitmap;

    // 屏幕的高度和宽度
    private int screenHeight;
    private int screenWidth;
    // 每个小格子的高度和宽度
    private int eachHeight;
    private int eachWidth;

    private Snake snake;
    private Food food;
    private Stone stone;
    private int[] listx;
    private int[] listy;

    private Timer timer = new Timer();

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            moveSnake();
            invalidate();
        }
    };

    public SnakeView(Context context) {
        super(context);
        this.context = context;
        listx = new int[100];
        listy = new int[100];
        // 获得屏幕的高和宽
        DisplayMetrics metrics = new DisplayMetrics();
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        windowManager.getDefaultDisplay().getMetrics(metrics);

        screenWidth = metrics.widthPixels;
        screenHeight = metrics.heightPixels;
        eachWidth = screenWidth / 20;
        eachHeight = screenHeight / 32;

        // 初始化图片
        headBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.head);
        bodyBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.body);
        foodBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.food);
        stoneBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.stone);

        this.initSnake();
        this.initFood();
        this.initstone();
        this.gameRun();
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = new Paint();
        paint.setColor(Color.GRAY);
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);//设置空心实心
        paint.setTextSize(40);

        drawLines(canvas, paint);   //1.
        drawSnake(canvas, paint);   //2.

        if (isCollide()) {
            canvas.drawText("Game Over!", screenWidth / 4, screenHeight / 3, paint);
            canvas.drawText("得分", screenWidth / 4, screenHeight / 2, paint);

            timer.cancel();

        } else {
            this.drawSnake(canvas, paint);
        }
        boolean flag = IsRectCollision(snake.getHead().getPointX(), snake.getHead().getPointY(), eachWidth, eachHeight,
                food.getPointX(), food.getPointY(), eachWidth, eachHeight);

        if (flag) {
            food = null;
            snake.getBodyList().add(new Body());
            initFood();
            initstone();
        } else {
            drawFood(canvas, paint);    //3.
            drawStone(canvas, paint);   //4.
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();

        SnakeDirection nowDir = snake.getSnakeDirection();
        int m = -screenHeight * x + screenHeight * screenWidth - screenWidth * y;
        int n = screenHeight * x - screenWidth * y;

        if ((m > 0 && n > 0) && (nowDir != SnakeDirection.DOWN)) {
            snake.setSnakeDirection(SnakeDirection.DOWN);

        } else if ((m > 0 && n < 0) && (nowDir != SnakeDirection.RIGHT)) {
            snake.setSnakeDirection(SnakeDirection.RIGHT);

        } else if ((m < 0 && n > 0) && (nowDir != SnakeDirection.LEFT)) {
            snake.setSnakeDirection(SnakeDirection.LEFT);

        } else if ((m < 0 && n < 0) && (nowDir != SnakeDirection.UP)) {
            snake.setSnakeDirection(SnakeDirection.UP);
        }
        return super.onTouchEvent(event);
    }


    /**************-----移动蛇------*****************/
    //移动蛇
    private void moveSnake() {
        int nowPointX = snake.getHead().getPointX();
        int nowPointY = snake.getHead().getPointY();
        if (snake.getSnakeDirection() == SnakeDirection.RIGHT) {
            changeSnakePosition(nowPointX, nowPointY);
            if (nowPointX >= screenWidth - eachWidth) {
                snake.getHead().setPointX(0);

            } else {
                snake.getHead().setPointX(nowPointX + eachWidth);
            }

        } else if (snake.getSnakeDirection() == SnakeDirection.DOWN) {
            changeSnakePosition(nowPointX, nowPointY);
            if (nowPointX >= screenHeight - eachHeight) {
                snake.getHead().setPointY(0);

            } else {
                snake.getHead().setPointY(nowPointY + eachHeight);
            }

        } else if (snake.getSnakeDirection() == SnakeDirection.LEFT) {
            changeSnakePosition(nowPointX, nowPointY);
            if (nowPointX <= 0) {
                snake.getHead().setPointX(screenWidth - eachWidth);
            } else {
                snake.getHead().setPointX(nowPointX - eachWidth);
            }

        } else if (snake.getSnakeDirection() == SnakeDirection.UP) {
            changeSnakePosition(nowPointX, nowPointY);
            if (nowPointY <= 0) {
                snake.getHead().setPointY(screenHeight - eachHeight);
            } else {
                snake.getHead().setPointY(nowPointY - eachHeight);
            }
        }
    }

    /**************-----判断方向------*****************/
    //改变蛇身的位置
    private void changeSnakePosition(int pointX, int pointY) {
        for (int i = snake.getBodyList().size() - 1; i > 0; i--) {
            snake.getBodyList().get(i).setPointX(snake.getBodyList().get(i - 1).getPointX());
            snake.getBodyList().get(i).setPointY(snake.getBodyList().get(i - 1).getPointY());
        }
        snake.getBodyList().get(0).setPointX(snake.getHead().getPointX());
        snake.getBodyList().get(0).setPointY(snake.getHead().getPointY());
    }


    /**
     * 矩形碰撞检测 参数为x,y,width,height
     * @param x1 第一个矩形的 x
     * @param y1 第一个矩形的 y
     * @param w1 第一个矩形的 w
     * @param h1 第一个矩形的 h
     * @param x2 第二个矩形的 x
     * @param y2 第二个矩形的 y
     * @param w2 第二个矩形的 w
     * @param h2 第二个矩形的 h
     * @return 是否碰撞
     */
    private boolean IsRectCollision(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) {
        if (x2 > x1 && x2 >= x1 + w1) {
            return false;

        } else if (x2 < x1 && x2 <= x1 - w2) {
            return false;

        } else if (y2 > y1 && y2 >= y1 + h1) {
            return false;

        } else if (y2 < y1 && y2 <= y1 - h2) {
            return false;
        } else {
            return true;
        }
    }

    //检测蛇头是否与蛇身碰撞
    // 检测蛇头与墙的碰撞
    private boolean isCollide() {
        boolean flag = false;
        for (int i = 0; i < snake.getBodyList().size(); i++) {
            flag = IsRectCollision(snake.getHead().getPointX(), snake.getHead().getPointY(),
                    eachWidth, eachHeight,
                    snake.getBodyList().get(i).getPointX(), snake.getBodyList().get(i).getPointY(),
                    eachWidth, eachHeight);

            for (int j = 0; j < 100; j++) {
                flag = IsRectCollision(snake.getHead().getPointX(), snake.getHead().getPointY(),
                        eachWidth, eachHeight, listx[j], listy[j], eachWidth, eachHeight);
                if (flag) {
                    break;
                }
            }
            if ((snake.getHead().getPointX() < 1) || (snake.getHead().getPointY() < 1) ||
                    (snake.getHead().getPointX() > screenWidth - 1) ||
                    (snake.getHead().getPointY() > screenHeight - 1)) {
                flag = true;
            }
            if (flag) {
                break;
            }
        }
        return flag;
    }

    /**************-----绘制图形------*****************/
    //画蛇
    private void drawSnake(Canvas canvas, Paint paint) {
        canvas.drawBitmap(headBitmap, snake.getHead().getPointX(), snake.getHead().getPointY(), paint);
        for (int i = 0; i < snake.getBodyList().size(); i++) {
            canvas.drawBitmap(bodyBitmap, snake.getBodyList().get(i).getPointX(),
                    snake.getBodyList().get(i).getPointY(), paint);
        }
    }

    //画网格线
    private void drawLines(Canvas canvas, Paint paint) {
        int startX = 0, startY = 0;
        for (int i = 0; i < 100; i++) {
            canvas.drawLine(0, startY, screenWidth, startY, paint);
            startY = startY + eachHeight;
        }
        for (int i = 0; i < 100; i++) {
            canvas.drawLine(startX, 0, startX, screenHeight, paint);
            startX = startX + eachWidth;
        }
        canvas.drawLine(0, 0, screenWidth, screenHeight, paint);
        canvas.drawLine(0, screenHeight, screenWidth, 0, paint);
    }

    //在界面上画出Stone
    private void drawStone(Canvas canvas, Paint paint) {
        if (true) {
            canvas.drawBitmap(stoneBitmap, stone.getPointX(), stone.getPointY(), paint);
            for (int i = 0; i < 100; i++) {
//                food = new Food(eachWidth * listx[i], eachHeight * listy[i], foodBitmap);
//                canvas.drawBitmap(stoneBitmap, listx[i], listy[i], paint);
            }
        }
    }

    //在界面上画出Food
    private void drawFood(Canvas canvas, Paint paint) {
        if (food != null) {
            canvas.drawBitmap(foodBitmap, food.getPointX(), food.getPointY(), paint);
        }
    }

    /**********-------初始化------*****************/
    //初始化stone
    private void initstone() {
        int x = new Random().nextInt(17);
        int y = new Random().nextInt(23);
        stone = new Stone(eachWidth * x, eachHeight * y, stoneBitmap);
        int i = 0, j = 0;
        listx[i++] = x;
        listy[j++] = y;
    }

    //开始游戏
    public void gameRun() {
        if (timer == null) {
            timer = new Timer();
        }

        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                handler.obtainMessage().sendToTarget();
                Log.e("Tag-timerTask:", "" + new Date());
            }
        }, 100, 400);
    }

    //初始化food
    private void initFood() {
        int x = new Random().nextInt(19);
        int y = new Random().nextInt(20);
        food = new Food(eachWidth * x, eachHeight * y, foodBitmap);
    }

    //初始化蛇
    private void initSnake() {
        List<Body> bodies = new ArrayList<>();
        Head head = new Head(eachWidth * 4, eachHeight * 2, headBitmap);
        Body body1 = new Body(eachWidth * 3, eachHeight * 2, bodyBitmap);
        Body body2 = new Body(eachWidth * 2, eachHeight * 2, bodyBitmap);
        Body body3 = new Body(eachWidth * 1, eachHeight * 2, bodyBitmap);
        Body body4 = new Body(eachWidth * 0, eachHeight * 2, bodyBitmap);

        bodies.add(body1);
        bodies.add(body2);
        bodies.add(body3);
        bodies.add(body4);

        snake = new Snake(head, bodies, SnakeDirection.RIGHT);
    }

}
